import {
    createRouter,
    createWebHashHistory,
    LocationQueryRaw
} from 'vue-router'
import {
    EXCEPTION_ROUTE,
    INIT_LIST,
    LAYOUT_CUSTOME_ROUTE,
    LOGIN_ROUTE,
    WHITE_LIST
} from './base'
import { createDiscreteApi } from 'naive-ui'
import { useAuthUserStore, useAuthMenuStore } from '@/store'
import { listenAdminLogout, removeAdminLogoutListener } from '@/events/login'
import { AUTH_USER_TOKEN_KEY } from '@/config/constant'

const { loadingBar } = createDiscreteApi(['loadingBar'])

const router = createRouter({
    history: createWebHashHistory(),
    scrollBehavior() {
        return {
            top: 0
        }
    },
    routes: INIT_LIST
})

router.beforeEach(async (to, _from, next) => {
    loadingBar.start()

    // 验证登录
    const isLoggedIn = !!localStorage.getItem(AUTH_USER_TOKEN_KEY)
    if (!isLoggedIn) {
        // 白名单直接放行
        if (WHITE_LIST.includes(to.name)) {
            next()
            return
        }

        // 跳转到404
        next(EXCEPTION_ROUTE)
        return
    }

    // 初始化动态菜单
    // 这里的操作实在用户刷新页面的时候执行的
    const menuStore = useAuthMenuStore()
    if (!menuStore.inited) {
        await initRouter()
        next({ path: to.fullPath })
        return
    }

    // 跳转到第一个路由
    if (to.name === LAYOUT_CUSTOME_ROUTE.name) {
        next({ name: menuStore.firstRoute?.name })
        return
    }

    next()
})

router.afterEach(() => {
    loadingBar.finish()
})

export default router

export async function initRouter() {
    const userStore = useAuthUserStore()
    const menuStore = useAuthMenuStore()

    // ---------------------------- 监听退出 -------------------------------
    listenAdminLogout(() => {
        // userStore
        userStore.logout()

        // menuStore
        menuStore.$reset()

        // 重置路由
        router.clearRoutes()
        INIT_LIST.forEach((r) => {
            router.addRoute(r)
        })

        // 跳转登录页
        // 跳转到登录页，携带当前页面路径和参数，以便回跳
        // 如果是错误页，则不携带
        const currentRoute = router.currentRoute
        let query: LocationQueryRaw | undefined = undefined
        if (
            !INIT_LIST.map((i) => i.name).includes(
                currentRoute.value.name as string
            )
        ) {
            query = {
                redirect: currentRoute.value.name as string,
                ...currentRoute.value.query
            }
        }
        router.push({
            name: LOGIN_ROUTE.name as string,
            query
        })

        // 停止登出监听
        removeAdminLogoutListener()
    })

    // ---------------------------- 初始化 -------------------------------
    await menuStore.init()

    const routes = menuStore.routes
    router.addRoute(LAYOUT_CUSTOME_ROUTE)
    routes.forEach((r) => {
        router.addRoute(LAYOUT_CUSTOME_ROUTE.name as string, r)
    })

    // 移除404，添加500
    setException('innter')
}

function setException(where: 'innter' | 'outer') {
    const exceptionName = EXCEPTION_ROUTE.name as string

    const outerHas = router.hasRoute(exceptionName)

    if (where === 'outer') {
        if (!outerHas) {
            router.removeRoute(exceptionName)
        }
    } else {
        if (outerHas) {
            router.removeRoute(exceptionName)
        }

        router.addRoute(<string>LAYOUT_CUSTOME_ROUTE.name, EXCEPTION_ROUTE)
    }
}
